package com.zhongkun.datahome.service.service.impl;

import com.alibaba.fastjson2.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.SimplifiedObjectMeta;
import com.zhongkun.datahome.common.utils.file.FileUtils;
import com.zhongkun.datahome.common.utils.http.HttpUtils;
import com.zhongkun.datahome.common.utils.uuid.UUID;
import com.zhongkun.datahome.service.config.AliyunOSSProperties;
import com.zhongkun.datahome.service.req.qry.file.DownloadBody;
import com.zhongkun.datahome.service.service.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * AbstractIFileService 抽取类
 * 根据filetype 实例化具体oss对象
 */
@Slf4j
@Component
public class FileServiceImpl implements IFileService {

    @Resource
    private OSS oss;

    @Resource
    private AliyunOSSProperties aliyunOSSProperties;


    @Override
    public String upload(MultipartFile file) throws Exception {
        // 构造上传文件唯一路径
        final String fileUrl = buildFileUrl(file, aliyunOSSProperties.getFileDir());
        // 上传阿里云
        oss.putObject(aliyunOSSProperties.getBucketName(), fileUrl, file.getInputStream());

        return aliyunOSSProperties.getDomain() + "/" + fileUrl;
    }

    @Override
    public String uploadData(byte[] data) {
        String fileUrl = aliyunOSSProperties.getFileDir() + "/" + UUID.fastUUID() + "." + FileUtils.getFileExtendName(data);
        // 上传阿里云
        oss.putObject(aliyunOSSProperties.getBucketName(), fileUrl, new ByteArrayInputStream(data));
        return aliyunOSSProperties.getDomain() + "/" + fileUrl;
    }

    public void download(HttpServletResponse response, DownloadBody body) {
        if (StringUtils.isBlank(body.getUrl())) {
            return;
        }

        String fileUrl = body.getUrl();
        String objectName = fileUrl.substring(aliyunOSSProperties.getDomain().length() + 1);

        InputStream in = null;
        OutputStream out = null;
        try {
            // 从OSS下载文件
            OSSObject ossObject = oss.getObject(aliyunOSSProperties.getBucketName(), objectName);
            in = ossObject.getObjectContent();

            out = new BufferedOutputStream(response.getOutputStream());

            int len;
            byte[] buf = new byte[1024];
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
        } catch (IOException e) {
            log.error("FileServiceImpl.download occur IOException: ", e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                log.error("FileServiceImpl.download close IO occur exception: ", e);
            }
        }
    }

    private String buildFileUrl(MultipartFile file, String fileDir) {
        final String originalFilename = file.getOriginalFilename();

        String fileName = UUID.fastUUID().toString();
        if (originalFilename != null) {
            final String suffix = originalFilename.substring(originalFilename.lastIndexOf('.'));
            fileName = fileName + suffix;
        }

        final StringBuilder fileUrl = new StringBuilder();
        if (!fileDir.endsWith("/")) {
            fileDir = fileDir.concat("/");
        }
        fileUrl.append(fileDir).append(fileName);
        return fileUrl.toString();
    }

    public String getFileSize(String url) {
        log.info("getFileSize properties: {}", JSON.toJSONString(aliyunOSSProperties));
        log.info("getFileSize url: {}", url.substring(aliyunOSSProperties.getDomain().length() + 1));

        // 创建OSSClient实例
        try {
            // 获取文件元数据
            SimplifiedObjectMeta objectMeta = oss.getSimplifiedObjectMeta(aliyunOSSProperties.getBucketName(), url.substring(aliyunOSSProperties.getDomain().length() + 1));
            // 获取文件大小
            long fileSize = objectMeta.getSize();
            log.info("getFileSize objectMeta: {}", objectMeta);
            return autoConvertFileSize(fileSize);
        } catch (Exception e) {
            log.info("获取文件大小失败", e);
        }
        return null;
    }

    public static String autoConvertFileSize(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        }
        double kb = bytes / 1024.0;
        if (kb < 1024) {
            return String.format("%.2f KB", kb);
        }
        double mb = kb / 1024.0;
        if (mb < 1024) {
            return String.format("%.2f MB", mb);
        }
        double gb = mb / 1024.0;
        return String.format("%.2f GB", gb);
    }
}
